package core.proto.annotation;

import static app.constants.CollabVizConstants.ANNOTATION_MARGIN;

import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.TextExtractor;

import org.apache.commons.io.FilenameUtils;
import org.jdesktop.swingx.mapviewer.GeoPosition;

import core.proto.AllComponents;
import core.proto.PaintDoc;
import core.proto.Util;
import core.proto.annotation.AnnotationModel.AnnotationLocation;
import core.proto.rightwindow.LeftRightCommunicator;
import core.proto.search.HtmlTextExtractor;
import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;

import static app.constants.CollabVizConstants.*;

/**
 * PostIt
 * 
 *
 */
public class DocAnnotationUI extends AnnotationUI {
	
	protected JButton send = new JButton();
	protected JButton delete = new JButton();
	
	protected double lastFrameX;
	protected double lastFrameY;

	public DocAnnotationUI(AnnotationModel model) throws CannotAddAnnotationException {
		super(model);
		
		this.setLocation(Location.Documents);
		this.setObjectName(FilenameUtils.getBaseName(AllComponents.getCurrentPath()));
		
		int x = 0;
		int y = 0;
		if (model instanceof DocAnnotationModel){
			DocAnnotationModel m = (DocAnnotationModel) model;
			x = m.getX();
			y = m.getY();
		}
		this.setupLabel(x,y);
		this.frame.setLocation(x,y);
		send.setLocation((int) frame.getX() + 140, (int) frame.getY() + frame.getHeight());
		
		delete.setLocation((int) frame.getX() + 165 , (int) frame.getY() -21);
		
		
		Icon icon = new ImageIcon(Util.getServerResource(
				"resources/img/forwardClean.png"));
		send.setIcon(icon);
		
		icon = new ImageIcon(Util.getServerResource(
				"resources/img/delete.png"));
		delete.setIcon(icon);
		
		
		if(!AllComponents.getCurrentPath().equals("NONE")){
			
		}
		
		frame.addComponentListener(
				new ComponentListener(){

					@Override
					public void componentHidden(ComponentEvent arg0) {
						send.setVisible(false);
						delete.setVisible(false);
					}

					@Override
					public void componentMoved(ComponentEvent arg0) {
						send.setLocation((int) frame.getX() + 140, (int) frame.getY() + frame.getHeight());
                		
                		delete.setLocation((int) frame.getX() + 165 , (int) frame.getY() -21);
					}

					@Override
					public void componentResized(ComponentEvent arg0) {
						
						
					}

					@Override
					public void componentShown(ComponentEvent arg0) {
						send.setLocation((int) frame.getX() + 140, (int) frame.getY() + frame.getHeight());
                		
                		delete.setLocation((int) frame.getX() + 165 , (int) frame.getY() -21);
						send.setVisible(true);
						delete.setVisible(true);
						
					}
					
				}
				);
		
			send.setBounds(new Rectangle(0, 0,80,40));
			send.setSize(60, 21);
			send.addActionListener(
					new ActionListener(){
						
						@Override
						public void actionPerformed(ActionEvent arg0) {
							deleteAnnotation ();
							
						}
					}
				);
			
			delete.setBounds(new Rectangle(0, 0,40,40));
			delete.setSize(30, 21);
	}
	

	/**
	 * Subclass can call this to setup the label if needed. 
	 */
	protected void setupLabel (int x, int y) {
		label = new JLabel();
		label.setOpaque(true);
		label.setBackground(LABEL_COLOR);
		label.setBounds(x,y,LABEL_W, LABEL_H);
		label.setSize(LABEL_W, LABEL_H);
		label.setBorder(BorderFactory.createLineBorder(Color.black));

		label.addMouseListener(new MouseAdapter() {
			public void mouseClicked (MouseEvent me) {
				if (me.getButton() == MouseEvent.BUTTON1) {
					show(label.getX(), label.getY());
					
					if(me.getClickCount() == 1){
						UserLogWriter.log2(Action.CLICK, loc.toString(), "Annotation", objectName, "null", "null", "Existing", textArea.getText());
					}
					else{
						UserLogWriter.log2(Action.DOUBLECLICK, loc.toString(), "Annotation", objectName, "null", "null", "Existing", textArea.getText());
					}
				}
			}
			
			public void mouseEntered(MouseEvent e) {
				if(label.isVisible()){
					highlightCorrespondingText(true);
				}
		    }

		    public void mouseExited(MouseEvent e) {
		    	if(label.isVisible()){
		    		highlightCorrespondingText(false);
		    	}
		    }
		});
	}
	
	public void highlightCorrespondingText(boolean toHilite){

		for(Annotation anno : AnnotationManager.getAnnotations(FilenameUtils.getBaseName(PaintDoc.staticDocKey), AnnotationLocation.DOC)){
			DocAnnotationModel m = (DocAnnotationModel) anno.getModel();
			DocAnnotationUI j = (DocAnnotationUI) anno.getView();
			
			if(j == this){
				PaintDoc doc = AllComponents.getDocumentPaintDoc();
				//System.out.println(doc.getHighlighter().getHighlights().length);
				
				if(toHilite){
					//System.out.println("IS THIS EXECUTED 2??? " + m.getDocKey() + m.getStartIndex() + " " + m.getEndIndex());
					doc.setHoverONHighlite(m.getStartIndex(), m.getEndIndex());
					
					/*File f = new File(AllComponents.getCurrentPath());
					TextExtractor extractor = null;
					try {
						extractor = new TextExtractor(new Source(f.toURI().toURL()));
						extractor.setIncludeAttributes(true);
					} catch (MalformedURLException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
					
					DocAnnotationModel docModel = ((DocAnnotationModel) model);
					
					
					textArea.setText(extractor.toString().substring(m.getStartIndex(), m.getEndIndex()));
					System.out.println("HELLLLLLLLLLLLLLLOOO?");*/
				}
				else{
					doc.setHoverOFFHighlite(m.getStartIndex(), m.getEndIndex());
				}
				
			}
		}
	}
	
	public void deleteCorrespondingText(){
		System.out.println("deleting corresponding text");
		for(Annotation anno : AnnotationManager.getAnnotations(FilenameUtils.getBaseName(PaintDoc.staticDocKey), AnnotationLocation.DOC)){
			DocAnnotationModel m = (DocAnnotationModel) anno.getModel();
			DocAnnotationUI j = (DocAnnotationUI) anno.getView();
			
			if(j == this){
				AllComponents.getDocumentPaintDoc().removeHighlite(m.getStartIndex(), m.getEndIndex());
				m.setDelete(true);
			}
		}
	}
	
	@Override
	public void addToPane (JLayeredPane pane) {
		super.addToPane(pane);
		pane.add(label, JLayeredPane.PALETTE_LAYER);
		parent.add(send, JLayeredPane.DRAG_LAYER);
		parent.add(delete, JLayeredPane.DRAG_LAYER);
		
		//ERIC, added to prevent weird labels in the corner while editing anno
		label.setVisible(false);
	}

	protected void doFocusLostModelViewUpdates () {
		/**SET CORRESPONDING TEXT TO NORMAL COLOR **/
		
		System.out.println(MouseInfo.getPointerInfo().getLocation().x + " " +  MouseInfo.getPointerInfo().getLocation().y);
		System.out.println( delete.getLocationOnScreen().getX()+ " " + (delete.getLocationOnScreen().getX() +  delete.getWidth()));
		if(MouseInfo.getPointerInfo().getLocation().x >= delete.getLocationOnScreen().getX() 
				&& MouseInfo.getPointerInfo().getLocation().x <= delete.getLocationOnScreen().getX() + delete.getWidth()
				&& MouseInfo.getPointerInfo().getLocation().y >= delete.getLocationOnScreen().getY() 
						&& MouseInfo.getPointerInfo().getLocation().y <= delete.getLocationOnScreen().getY() + delete.getHeight()){
			textArea.setText("");
			model.setUserText("");
			deletehide ();
			deleteAnnotation ();
			LeftRightCommunicator.annotationUpdated(this);
			AnnotationManager.writeFile(model.getDocKey());
		}
		else{
			highlightCorrespondingText(false);
			DocAnnotationModel model = (DocAnnotationModel) this.model; 
			model.setX(frame.getX());
			model.setY(frame.getY());
	
			shrink(model.getX(), model.getY());
		}

	}
	
	public void hide() {
		frame.setVisible(false);
		label.setVisible(false);
		send.setVisible(false);
		delete.setVisible(false);
	}
	
	public void deletehide(){
		frame.setVisible(false);
		label.setVisible(false);
		send.setVisible(false);
		delete.setVisible(false);
		
		deleteCorrespondingText();
	}
	
	public void deleteUndo(){
		//frame.setVisible(true);
		label.setVisible(true);
		
		for(Annotation anno : AnnotationManager.getAnnotations(FilenameUtils.getBaseName(PaintDoc.staticDocKey), AnnotationLocation.DOC)){
			DocAnnotationModel m = (DocAnnotationModel) anno.getModel();
			DocAnnotationUI j = (DocAnnotationUI) anno.getView();
			
			if(j == this){
				PaintDoc doc = AllComponents.getDocumentPaintDoc();
				//System.out.println(doc.getHighlighter().getHighlights().length);
				
				doc.setHoverOFFHighlite(m.getStartIndex(), m.getEndIndex());
				
			}
		}
	}

	@Override
	public void shrink(double x, double y) {
		label.setLocation((int) x, (int) y);
		label.setBounds((int) x, (int) y, LABEL_W, LABEL_H);
		String txt = textArea.getText();
		model.setUserText(txt);
		label.setText(abbreviateLabelText(txt));

		parent.moveToFront(label);
		
		frame.setVisible(false);
		send.setVisible(false);
		delete.setVisible(false);
		label.setVisible(true);
	}

	public void removeFromPane() {
		parent.remove(frame);
		parent.remove(label);
		parent.remove(send);
		parent.remove(delete);
		parent.repaint();
	}

	public void show(int x, int y) {
		label.setVisible(false);
		super.show(x, y);
		send.setLocation((int) frame.getX() + 140, (int) frame.getY() + frame.getHeight());
		
		delete.setLocation((int) frame.getX() + 165 , (int) frame.getY() -21);
		
		send.setVisible(true);
		delete.setVisible(true);
	}
	
	public void changeToAltBackground(){
		label.setBackground(LABEL_COLOR_ALT);
	}
	
	public void revertBackground(){
		label.setBackground(LABEL_COLOR);
	}
	
	public void setAnnotationText(String text){
		textArea.setText(text);
	}
}
